﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CWB.Web;
using System.Globalization;

namespace CWB.Web.Misc
{
    public static class DateTimeUtil
    {
        //public static double UserTimeZoneOffet
        //{
        //    get { return AgileBet.Star.Web.BLL.SessionManager.GetCurrentTrading().TimeZoneUtcOffset; }
        //}
        public static DateTime ToServerDateTime(this DateTime userClientDateTime, double userTimeZoneOffset)
        {
            DateTime date = DateTime.SpecifyKind(userClientDateTime, DateTimeKind.Utc);
            return DateTime.SpecifyKind(TimeZone.CurrentTimeZone.ToLocalTime(date.AddMinutes(-userTimeZoneOffset)), DateTimeKind.Local);
        }

        /// <summary>
        /// Convert Server DateTime To the user date time.
        /// </summary>
        /// <param name="serverDateTime">The server date.</param>
        /// <param name="userTimeZoneOffset">The user time zone offset in minutes.</param>
        /// <returns></returns>
        public static DateTime ToClientDateTime(this DateTime serverDateTime, double userTimeZoneOffset)
        {
            DateTime utcDateTime = serverDateTime.ToUniversalTime();
            return serverDateTime == DateTime.MinValue ?
                        serverDateTime : // This workaround will (for users from OP site) make last-login-time feature fail
                        DateTime.SpecifyKind(utcDateTime.AddMinutes(userTimeZoneOffset), DateTimeKind.Unspecified);
        }

        public static DateTime ToDayBasedOnClient(this DateTime serverDate, double userTimeZoneOffset)
        {
            return serverDate.ToClientDateTime(userTimeZoneOffset).Date.ToServerDateTime(userTimeZoneOffset);
        }

        public static bool ParseDate(string time, out DateTime dateTime)
        {

            string format = "dd/MM/yyyy";
            if (!DateTime.TryParseExact(time, format, null, DateTimeStyles.None, out dateTime))
            {
                format = "MM/dd/yyyy";
                if (!DateTime.TryParseExact(time, format, null, DateTimeStyles.None, out dateTime))
                {
                    return false;
                }
            }

            return true;
        }

        ///// <summary>
        ///// Convert User DateTime to  server date time.
        ///// </summary>
        ///// <param name="userDate">The user date.</param>
        ///// <returns></returns>
        //public static DateTime ToServerDateTime(this DateTime userDate)
        //{
        //    return userDate.ToServerDateTime(UserTimeZoneOffet);
        //}

        //public static DateTime ToClientDateTime(this DateTime serverDate)
        //{
        //    return serverDate.ToClientDateTime(UserTimeZoneOffet);
        //}

        /// <summary>
        /// More infor, please refer 
        /// http://msdn.microsoft.com/en-us/library/az4se3k1.aspx
        /// http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="lang"></param>
        /// <returns></returns>
        public static string ToFormatString(this DateTime dateTime, string lang)
        {
            CultureInfo format = CultureInfo.GetCultureInfo(lang);
            return ToFormatString(dateTime, format);
        }

        public static string ToFormatString(this DateTime dateTime, CultureInfo format)
        {
            if (format.Name == "zh-CN" || format.Name == "ko-KR")
            {
                return dateTime.ToString("m", format) + ", " + dateTime.ToString("T", format);
            }
            if (format.Name == "zh-TW")
            {
                return dateTime.ToString("m", format) + ", " + dateTime.ToString("T", format).Split(' ')[1];
            }
            return dateTime.ToString("dd MMM, HH:mm", format);//28 Mar 2011
        }

        /// <summary>
        /// 4 Feb 2010, 2010年 2月4日
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="cultureName"></param>
        /// <returns></returns>
        public static string ToFormatShortDate(this DateTime dateTime, string cultureName)
        {
            CultureInfo format = CultureInfo.GetCultureInfo(cultureName);
            return ToFormatShortDate(dateTime, format);
        }

        public static string ToFormatShortDate(this DateTime dateTime, CultureInfo format)
        {
            switch (format.Name)
            {
                case "zh-CN":
                case "zh-TW":
                    return dateTime.Year + "年" + dateTime.ToString("m", format);
                case "th-TH":
                    ///The reason we use this kind of format for th-th language is that its year is 553?
                    return dateTime.ToString("dd MMM ", format) + dateTime.Year;
                case "ko-KR":
                    return dateTime.Year + "년" + dateTime.ToString("m", format);
                default:
                    return dateTime.ToString("dd MMM yyy", format);
            }
        }

        /// <summary>
        /// 4 Feb 2010, 2010年 2月4日
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="lang"></param>
        /// <returns></returns>
        public static string ToFormatDate(this DateTime dateTime, string lang)
        {
            CultureInfo format = CultureInfo.GetCultureInfo(lang);
            return ToFormatDate(dateTime, format);
        }

        /// <summary>
        /// 4 Feb, 2月4日
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        public static string ToFormatDate(this DateTime dateTime, CultureInfo format)
        {
            switch (format.Name)
            {
                case "zh-CN":
                case "zh-TW":
                    return dateTime.ToString("m", format);
                case "th-TH":
                    ///The reason we use this kind of format for th-th language is that its year is 553?
                    return dateTime.ToString("dd MMM ", format);
                case "ko-KR":
                    return dateTime.ToString("m", format);
                default:
                    return dateTime.ToString("dd MMM", format);
            }
        }

        public static string GetDateMonthStr(DateTime date, CultureInfo language)
        {
            switch (language.Name.ToLower())
            {
                case "zh-cn":
                case "zh-tw":
                    return date.ToString("M月dd日");
                // return string.Format("{0}{1}{2}{3}", date.Month.ToString(), "月", date.ToString("dd"), "日");
                case "vi-vn":
                    return date.ToString("dd 'Thg'M", language);
                case "th-th":
                    return date.ToString("dd MMM", language);//string.Format("{0} {1}", GetMonthLocalize(date.Month), date.ToString("dd"));
                case "ko-kr":
                    return date.ToString("M월dd일"); // string.Format("{0}{1}{2}{3}", date.Month.ToString(), "월", date.ToString("dd"), "일");
            }
            return date.ToString("dd MMM", language);
        }

        public static string GetDateMonthStr(DateTime date)
        {
            return date.ToString("dd/MM");
        }

        public static string GetDDMMYYYYStr(DateTime date, string cultureName)
        {
            switch (cultureName)
            {
                case "zh-cn":
                case "zh-tw":
                    return date.ToString("yyyy年M月dd日");
                //case "vi-vn":
                //    return date.ToString("dd, 'Tháng' M yyyy", language);
                //case "th-th":
                //    // Thai's Calendar starts at 553 years earlier normal Calendar
                //    return date.ToString("dd MMM ", language) + date.Year.ToString();
                case "ko-kr":
                    return date.ToString("yyyy년M월dd일");

                case "en-gb":
                    return date.ToString("dd MMM yyyy");
                // return string.Format("{4}{5}{0}{1}{2}{3}", date.Month.ToString(), "월", date.ToString("dd"), "일", date.Year.ToString(), "년");
                default:
                    return date.ToString("dd MMM yyyy");
            }
            //return date.ToString("dd MMM yyyy", language);
        }

        public static string FormatDate(this DateTime date, CultureInfo cultureInfo)
        {
            return GetDDMMYYYYStr(date, cultureInfo.Name.ToLower());
        }

        public static string FormatShortDate(this DateTime date, CultureInfo cultureInfo)
        {
            return GetDDMMStr(date, cultureInfo);
        }

        public static double GetUtcOffset(string timeZone)
        {
            TimeSpan timeOffSet = new TimeSpan(-4, 0, 0); // Default time Zone (GMT -4)                
            if (!string.IsNullOrEmpty(timeZone))
            {
                string strTimeOffset = timeZone.Replace("GMT", "").Trim().Replace("+", "");
                if (!TimeSpan.TryParse(strTimeOffset, out timeOffSet))
                {
                    timeOffSet = new TimeSpan(-4, 0, 0);
                }
            }

            // default is System TimeZone
            return timeOffSet.TotalMinutes;
        }

        public static string GetMMMddWeekDay(DateTime date, bool includeWeekday, CultureInfo language)
        {
            string weekdayFormat = includeWeekday ? " (ddd)" : string.Empty;
            switch (language.Name.ToLower())
            {
                case "zh-cn":
                case "zh-tw":
                    return date.ToString("M月dd日" + weekdayFormat);
                case "vi-vn":
                    return date.ToString("dd 'Thg'M" + weekdayFormat, language);
                case "th-th":
                    return date.ToString("dd MMM" + weekdayFormat, language);
                case "ko-kr":
                    return date.ToString("M월dd일" + weekdayFormat);
                default:
                    return date.ToString("MMM dd" + weekdayFormat, language);
            }
        }

        public static string GetDDMMStr(DateTime date, CultureInfo language)
        {
            switch (language.Name.ToLower())
            {
                case "zh-cn":
                    return date.ToString("dd日M月, hh:mm:ss");
                case "zh-tw":
                    return date.ToString("dd日M月, hh:mm:ss");
                case "vi-vn":
                    return date.ToString("dd 'Thg'M, hh:mm:ss", language);
                case "th-th":
                    return date.ToString("dd MMM, hh:mm:ss", language);
                case "ko-kr":
                    return date.ToString("M월dd일, hh:mm:ss");
                default:
                    return date.ToString("dd MMM, hh:mm:ss", language);
            }
        }
    }
}
